home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 1.iso / dist / fw_ddd.idb / usr / freeware / share / ddd-3.3.1 / vsllib / flowplus.vsl.z / flowplus.vsl
Text File  |  2001-10-09  |  7KB  |  285 lines

  1. // $Id: flowplus.vsl,v 1.2 2000/06/09 13:06:26 andreas Exp $ --
  2. // Drawing flowcharts with gotos and labels
  3.  
  4. // Copyright (C) 1993 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@gnu.org>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.gnu.org/software/ddd/',
  27. // or send a mail to the DDD developers <ddd@gnu.org>.
  28.  
  29. #include "std.vsl"
  30. #include "slopes.vsl"
  31. #include "arcs.vsl"
  32.  
  33.  
  34. // Extended flow charts
  35.  
  36. // Version
  37. flowplus_version() = "$Revision: 1.2 $";
  38.  
  39. #include "flow.vsl"
  40. #include "list.vsl"
  41.  
  42.  
  43. // Data structures
  44. //
  45. // frag = (box, connect, labels, gotos)
  46. //
  47. // labels = (label, labels...)
  48. // 
  49. // gotos = (label, labels...)
  50. // 
  51. // label = (id, pos, stuff...)
  52. // 
  53. // We have:
  54. // 
  55. // box     - the created picture
  56. // connect - the distance of connecting lines and left side
  57. // labels  - the list of all labels
  58. // gotos   - the list of all gotos
  59. // id      - the id of a label
  60. // pos     - the distance of a label from upper-left corner
  61.  
  62.  
  63. // Helpers
  64.  
  65. // frag(box) creates a fragment from a box
  66.  
  67. frag((box, connect, labels, gotos)) = (box, connect, labels, gotos);
  68. frag(box) = fallbackFlow(box);
  69.  
  70.  
  71. // searchLabel() searches a label named ID; returns () if not found
  72.  
  73. searchLabel(_, []) = ();
  74. searchLabel(search, [label, labels...]) = 
  75.   let (id, _...) = label in
  76.     if (search = id) then label else searchLabel(search, labels) fi;
  77.  
  78.  
  79. // expandLines() expands the lines of labels and gotos.
  80.  
  81. expandLines([]) = 0;
  82. expandLines([label, labels...]) = 
  83.   let (_, pos, _...) = label in
  84.   (vspace(pos) | (vfix(hrule()) ^ hspace(flow_space()))) ^ expandLines(labels);
  85.  
  86.  
  87. // drawConnect() connects two positions
  88.  
  89. drawConnectDown(start, end) =
  90.   vspace(start)
  91. | vfix(hrule())
  92. | hspace(flow_space()) & vrule() & vspace(end - start - 1)
  93. | vfix(hrule());
  94.  
  95. drawConnectUp(start, end) =
  96.   vspace(end)
  97. | vfix(hrule())
  98. | hspace(flow_space()) & vrule() & vspace(start - end - 1)
  99. | vfix(hrule());
  100.  
  101. drawConnect(start, end) =
  102.   if (start < end)
  103.   then drawConnectDown(start, end)
  104.   else drawConnectUp(start, end)
  105.   fi;
  106.  
  107.  
  108. // connectGoto() connects a goto with a label; the goto is removed
  109. // from the list
  110.  
  111. connectGoto(frag, _, []) = frag; // Label nicht gefunden
  112.  
  113. connectGoto(frag, goto, label) =
  114.  
  115.   let (box, connect, labels, gotos) = frag,
  116.       (_, gotopos, _...) = goto,
  117.       (_, labelpos, _...) = label in
  118.  
  119.     (newbox, connect, labels, select(gotos, goto))
  120.  
  121.     where newbox = ((box & trailer)
  122.        where trailer = drawConnect(gotopos, labelpos) 
  123.           ^ expandLines(labels) ^ expandLines(gotos));
  124.  
  125.  
  126. // resolveGoto() searches a specific goto und attempts a connection
  127.  
  128. resolveGoto(frag, goto) =
  129.   connectGoto(frag, goto, label)
  130.     where label = 
  131.       (let (gotoid, _...) = goto, (_, _, labels, _) = frag
  132.          in searchLabel(gotoid, labels));
  133.  
  134.  
  135. // _resolveGotos() calls resolveGoto() for all list elements
  136.  
  137. _resolveGotos(frag, []) = frag;
  138. _resolveGotos(frag, [goto, gotos...]) =
  139.   _resolveGotos(resolveGoto(frag, goto), gotos);
  140.  
  141.  
  142. // resolveGotos() resolves all references *within a fragment*; if
  143. // successful, the goto is removed from the list and a path to the
  144. // label is drawn.
  145.  
  146. resolveGotos(frag) =
  147.   let (_, _, _, gotos) = frag in
  148.     _resolveGotos(frag, gotos);
  149.  
  150. // moveLabels() moves a list of references down by OFFSET
  151.  
  152. moveLabels(_, []) = [];
  153. moveLabels(offset, [label, labels...]) =
  154.   let (id, pos, ...) = label in
  155.   [(id, vspace(pos | offset), ...), moveLabels(offset, labels)...];
  156.  
  157.  
  158. // joinFragments() joins two fragments, resolving all cross references
  159. // (goto/label pairs)
  160.  
  161. joinTwoFragments(max, sep, f1, f2) =
  162.   let frag1 = frag(f1), frag2 = frag(f2) in
  163.   let newfrag = 
  164.   align(frag1, max) 
  165. | align(sep, max) & hfill() 
  166. | align(frag2, max) in
  167.   let 
  168.     (box1, _, labels1, gotos1) = frag1,
  169.     (_, _, labels2, gotos2) = frag2,
  170.     (sepbox, _) = sep,
  171.     voffset = vspace(box1 | sepbox),
  172.     newlabels = labels1 :: moveLabels(voffset, labels2),
  173.     newgotos  = gotos1  :: moveLabels(voffset, gotos2) in
  174.     (newfrag, max, newlabels, newgotos);
  175.  
  176.  
  177. joinFragments(_, frag1) = resolveGotos(frag(frag1));
  178.  
  179. joinFragments(sep, frag1, frag2) =
  180.   resolveGotos(joinTwoFragments(max_connect(frag1, frag2), sep, frag1, frag2));
  181.  
  182. joinFragments(sep, frag1, frag2, frag3, ...) =
  183.   joinFragments(sep, 
  184.     joinFragments(sep, frag1, frag2), joinFragments(sep, frag3, ...));
  185.  
  186.  
  187.  
  188. // showRemainingGotos() displays remaining gotos and labels
  189.  
  190. tagLabel(pos, tag) =
  191.   vspace(pos - (tag / 2)) | tag;
  192.  
  193. tagLabels([]) = 0;
  194. tagLabels([label, labels...]) = 
  195.   let (id, pos, _...) = label in
  196.     let tag = veven(vcenter(hrule() | hspace(e_arrow())) & circle(id)) in
  197.       tagLabel(pos, tag) ^ tagLabels(labels);
  198.  
  199. tagGoto(pos, tag) =
  200.   vspace(pos - (tag / 2)) | tag;
  201.  
  202. tagGotos([]) = 0;
  203. tagGotos([goto, gotos...]) =
  204.   let (id, pos, _...) = goto in
  205.     let tag = veven(vcenter(e_arrow()) & circle(id)) in
  206.       tagGoto(pos, tag) ^ tagGotos(gotos);
  207.  
  208. showRemainingGotos(frag) =
  209.   let (box, _, labels, gotos) = frag in
  210.     ((box & trailer, 0, labels, gotos)
  211.       where trailer = tagLabels(labels) ^ tagGotos(gotos));
  212.  
  213.  
  214. // removeLabels() removes labels from a fragment
  215. // (e.g. they may not be visible outside a procedure)
  216.  
  217. removeLabels((box, connect, _, gotos)) =
  218.   (box, connect, [], gotos);
  219.  
  220.  
  221.  
  222. // labels and gotos
  223.  
  224. labelFlow(id) = frag
  225.   where frag = (box, connect, labels, gotos)
  226.     where box = vrule() & (veven(vfix(w_arrow())) | fill()),
  227.       connect = 0,
  228.       labels = [(id, vspace(veven(w_arrow()) / 2))],
  229.       gotos = [];
  230.  
  231. gotoFlow(id) = frag
  232.   where frag = (box, connect, labels, gotos)
  233.     where box = vrule() & (hrule() | fill()),
  234.       connect = 0,
  235.       labels = [],
  236.       gotos = [(id, 0)];
  237.  
  238.  
  239. // Sequential list (of fragments or whatsoever)
  240.  
  241. // Fragment separator
  242. _fragsep() = (vspace(flow_space() | flow_space()), 0); 
  243.  
  244. // Fragment connector
  245. _fragconnect() = (vrule() & vspace(flow_space()), 0);
  246.  
  247.  
  248. fragFlow() = (0, 0, [], []);
  249. fragFlow(frag) = frag;
  250.  
  251. // Ignore goto in goto/label pair
  252.  
  253. fragFlow(gotoFlow(id1), labelFlow(id2)) =
  254.   if (id1 = id2)
  255.   then fragFlow(labelFlow(id2))
  256.   else joinFragments(_fragconnect(), gotoFlow(id1), labelFlow(id2))
  257.   fi;
  258.  
  259. // Leave space after goto
  260.  
  261. fragFlow(gotoFlow(id), frag2) = 
  262.   joinFragments(_fragsep(), gotoFlow(id), frag2);
  263.  
  264.  
  265. // Otherwise: connect
  266.  
  267. fragFlow(frag1, frag2) = 
  268.   joinFragments(_fragconnect(), frag1, frag2);
  269.  
  270. fragFlow(frag1, gotoFlow(id), ...) = 
  271.   fragFlow(frag1, fragFlow(gotoFlow(id), ...));
  272. fragFlow(frag1, frag2, ...) = 
  273.   fragFlow(fragFlow(frag1, frag2), ...);
  274.  
  275.  
  276.  
  277. // outputFlow() should be called before each output
  278. // (by defining __output() accordingly)
  279.  
  280. getBox((box, _, _, _)) = box;
  281.  
  282. outputFlow((box, connect, gotos, labels)) = 
  283.   getBox(showRemainingGotos((box, connect, gotos, labels)));
  284. outputFlow(box) = box;
  285.